正樣本的數量越多,Haar特徵分類模型表現的效果越好,但是要獲取大量的照片是一件非常麻煩的事,因此我們需要利用程式來幫助我們產生更多的照片。
增加車牌數量
將四個邊的長寬各10%刪除來產生新的圖片,如次一來,每一張圖片都能產生四張新的圖片。
從新計算新圖片尺寸
from PIL import Image
path = 'Haar-Training_carPlate/training/positive/'
fp = open(path + 'info.txt', 'r')
line = fp.readline()
count = 73 #產生的圖片編號由此開始
rettext = ''
while line:
data = line.split(' ')
img = Image.open(path + data[0]) #讀入圖形檔
x = int(data[2]) #圖形X坐標
y = int(data[3]) #圖形Y坐標
w = int(data[4]) ##圖形寬
h = int(data[5]) ##圖形高
reduceW = 30 #減少的的寬度
reduceH = int(reduceW*0.75) #減少的的高度
multi = float(300/(300-reduceW)) #原圖與新圖比例
neww = int(w*multi) #新圖的寬
newh = int(h*multi) #新圖的高
移除左上角圖
if (x-reduceW)>5 and (y-reduceH)>5: #左上角有空間才移除左上角
count += 1 #編號加1,此數值會做為檔名用
newimg = img.crop((reduceW, reduceH, 300, 225)) #擷取圖形
newimg = newimg.resize((300, 225), Image.ANTIALIAS) #放大圖形
newimg.save(path + 'rawdata/bmpraw{:0>3d}.bmp'.format(count), 'bmp') #存檔
newx = int((x-reduceW)*multi-reduceW*(multi-1)/2) #新圖X坐標
newy = int((y-reduceH)*multi-reduceH*(multi-1)/2) #新圖Y坐標
rettext = rettext+'rawdata/bmpraw{:0>3d}.bmp'.format(count)+' '+'1'+' '+str(newx)+' '+str(newy)+' '+str(neww)+' '+str(newh)+'\n' #記錄新圖資料
移除右上角圖
if (x+w)<(300-reduceW-5) and y>(reduceW+5):
count += 1
newimg = img.crop((0, reduceH, (300-reduceW), 225))
newimg = newimg.resize((300, 225), Image.ANTIALIAS)
newimg.save(path + 'rawdata/bmpraw{:0>3d}.bmp'.format(count), 'bmp')
newx = int(x*multi)
newy = int((y-reduceH)*multi-reduceH*(multi-1)/2)
rettext = rettext+'rawdata/bmpraw{:0>3d}.bmp'.format(count)+' '+'1'+' '+str(newx)+' '+str(newy)+' '+str(neww)+' '+str(newh)+'\n'
移除左下角圖
if (x-reduceW)>5 and (y+h)<(225-reduceH-5):
count += 1
newimg = img.crop((reduceW, 0, 300, 225-reduceH))
newimg = newimg.resize((300, 225), Image.ANTIALIAS)
newimg.save(path + 'rawdata/bmpraw{:0>3d}.bmp'.format(count), 'bmp')
newx = int((x-reduceW)*multi-reduceW*(multi-1)/2)
newy = int(y*multi)
rettext = rettext+'rawdata/bmpraw{:0>3d}.bmp'.format(count)+' '+'1'+' '+str(newx)+' '+str(newy)+' '+str(neww)+' '+str(newh)+'\n'
移除右下角圖
if (x+w)<(300-reduceW-5) and (y+h)<(225-reduceH-5):
count += 1
newimg = img.crop((0, 0, (300-reduceW), 225-reduceH))
newimg = newimg.resize((300, 225), Image.ANTIALIAS)
newimg.save(path + 'rawdata/bmpraw{:0>3d}.bmp'.format(count), 'bmp')
newx = int(x*multi)
newy = int(y*multi)
rettext = rettext+'rawdata/bmpraw{:0>3d}.bmp'.format(count)+' '+'1'+' '+str(newx)+' '+str(newy)+' '+str(neww)+' '+str(newh)+'\n'
將資料rettext寫入到Info.txt檔案中。
line = fp.readline()
fp.close()
fpmake = open(path + 'Info.txt', 'a') #以新增資料方式開啟檔案
fpmake.write(rettext) #寫入檔案
fpmake.close()
print('產生新圖片結束!')
訓練Haar
haartraining.exe -data #輸入儲存結果檔案路徑 -vec #輸入正樣本向量路徑
-bg #負樣本資料路徑 -npos #正樣本圖形數量 -nneg #負樣本圖形數量 -nstages #數字越高準確率越高 -mem #記憶體大小 -mode #訓練模式 -w #寬 -h #高
車牌偵測
import cv2
img = cv2.imread('realPlate/resizejpg001.jpg') #讀取要辨識的圖形
detector = cv2.CascadeClassifier('haar_carplate.xml') #讀取Haar模型
signs = detector.detectMultiScale(img, minSize=(76, 20), scaleFactor=1.1, minNeighbors=4) #辨識
#minSize:檢測矩形最小尺寸,scaleFactor:檢測矩形放大比例,minNeighbors:偵測物件周圍有多少個相鄰的矩形
if len(signs) > 0 : #有偵測到車牌
for (x, y, w, h) in signs: #逐一框選出車牌
cv2.rectangle(img, (x, y), (x+w, y+h), (0, 0, 255), 2)
print(signs)
else:
print('沒有偵測到車牌!')
cv2.imshow('Frame', img) #顯示圖形
cv2.waitKey(0) #當按下鍵盤上的任何鍵時,視窗將被關閉
cv2.destroyAllWindows() #關閉所有的 OpenCV 視窗。
---20231014---